ident = '$Id: tracer.py 109 2006-06-05 18:46:37Z trevor $'

# Tracer
import sys,os,wx,common
import wx.stc as stc

class tracer( wx.Frame ):
	def __init__( self, parent ):
		title = "ESM Tracer"
		wx.Frame.__init__( self, parent, -1, title, size=(400,200),
						  style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE )
		self.actions = []		# List of actions
		self.account_manager= parent
		self.action_index	= 0
		# Set the close event for this frame
		self.Bind( wx.EVT_CLOSE, self.on_close )
		# Our main sizer
		sizer = wx.BoxSizer( wx.VERTICAL )
		# The list
		self.list = wx.ListCtrl( self, -1, style=wx.LC_REPORT )
		sizer.Add( self.list, 1, wx.EXPAND  )
		info = wx.ListItem()
		info.m_mask = wx.LIST_MASK_TEXT # | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
		#info.m_image = -1
		info.m_format = 0
		info.m_text = "-"
		self.list.InsertColumnInfo(0, info)
		info.m_text = "URL"
		self.list.InsertColumnInfo(1, info)
		info.m_text = "Method"
		self.list.InsertColumnInfo(2, info)
		# Connect the activation event
		self.list.Bind( wx.EVT_LIST_ITEM_ACTIVATED, self.on_view_action )
		# Let' get ready
		self.resize_columns()
		self.sizer = sizer
		self.SetSizer( self.sizer )
		self.SetAutoLayout( 1 )
		# Windows needs this call
		self.Layout()

	def add_new_action( self, url, method, soap_out, soap_in ):
		self.actions.append( ( url, method, soap_out, soap_in ) )
		self.action_index = self.action_index + 1
		x = self.list.GetItemCount()
		self.list.InsertStringItem( x, str( x + 1 ) )
		self.list.SetStringItem( x , 1, url )
		self.list.SetStringItem( x , 2, method )
		# self.list.SetItemData( x, oid )
		self.resize_columns()

	def resize_columns( self ):
		if len( self.actions ) < 1:
			size = 50
		else:
			size = wx.LIST_AUTOSIZE
		for i in range( self.list.GetColumnCount() ):
			self.list.SetColumnWidth( i, size )

	def on_close( self, event ):
		common.tracer = None
		self.Destroy()

	def on_view_action( self, event ):
		sel = common.get_selected_in_list( self.list )
		if len( sel ) < 1: return
		index = sel[0]
		url, method, soap_out, soap_in = self.actions[ index ]
		av = tracer_frame( self, str( index + 1 ), url, method, soap_out, soap_in )
		av.Show()
		# lose our referenct to it
		del av

#################################
class tracer_frame( wx.Frame ):
	'''The ESM Tracer Action Viewer'''
	def __init__( self, parent, index, url, method, soap_out, soap_in ):
		title 		= "%s - %s => %s" % ( index, method, url )
		wx.Frame.__init__( self, parent, -1, title, size=(600,600),
						  style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE )
		# Set the close event for this frame
		self.Bind( wx.EVT_CLOSE, self.on_close )
		# build the sizer and the splitter window
		sizer 		= wx.BoxSizer( wx.HORIZONTAL )
		splitter 	= wx.SplitterWindow( self, -1, style=wx.SP_3DSASH | wx.SP_NOBORDER )
		sizer.Add( splitter, 1, wx.EXPAND )
		# Build the SOAP OUT panel
		out_sizer 	= wx.BoxSizer( wx.VERTICAL )
		out_panel	= wx.Panel( splitter, -1 )
		out_panel.SetSizer( out_sizer )
		label 		= wx.StaticText( out_panel, -1, "SOAP Sent" )
		out_editor	= tracer_editor( out_panel )
		out_editor.Show()
		out_editor.SetWrapMode( stc.STC_WRAP_WORD )
		out_editor.SetText( soap_out )
		out_editor.SetReadOnly( True )
		out_sizer.Add( label, 0, wx.EXPAND )
		out_sizer.Add( out_editor, 1, wx.EXPAND )
		# Build the SOAP IN panel
		in_sizer 	= wx.BoxSizer( wx.VERTICAL )
		in_panel	= wx.Panel( splitter, -1 )
		in_panel.SetSizer( in_sizer )
		label 		= wx.StaticText( in_panel, -1, "SOAP Received" )
		in_editor	= tracer_editor( in_panel )
		in_editor.Show()
		in_editor.SetWrapMode( stc.STC_WRAP_WORD )
		try:
			in_editor.SetText( soap_in )
		except:
			try:
				in_editor.SetText( soap_in.encode('utf-8') )
			except:
				pass
		in_editor.SetReadOnly( True )
		in_sizer.Add( label, 0, wx.EXPAND )
		in_sizer.Add( in_editor, 1, wx.EXPAND )
		# Fill the splitter
		splitter.SetMinimumPaneSize(20)
		splitter.SplitHorizontally( out_panel, in_panel)
		splitter.SetSashPosition(50)
		# Show all
		self.SetSizer( sizer )
		self.SetAutoLayout( 1 )
		# Windows needs this call
		self.Layout()

	def on_close( self, event ):
		self.Destroy()

class tracer_editor( stc.StyledTextCtrl ):
	def __init__( self, parent ):
		stc.StyledTextCtrl.__init__( self, parent, -1 )
		# lets go
		self.SetStyleBits( 7 )
		self.StyleSetSpec( stc.STC_STYLE_DEFAULT, "size:%s,face:%s" % (common.default_font_size, common.default_font_family ))
		self.SetEOLMode( stc.STC_EOL_LF )
		self.SetLexer( stc.STC_LEX_HTML )
		self.SetStyleBits( 7 )
		self.SetMargins( 10, 0 )
		self.SetMarginType( 2, stc.STC_MARGIN_NUMBER )
		self.SetMarginSensitive( 2, True )
		self.SetMarginWidth( 2, 15 )
		self.SetBufferedDraw( 1 )
		self.SetEdgeMode( stc.STC_EDGE_LINE )
		self.SetEdgeColumn( 80 )
		self.SetTabWidth( 4 )
		self.SetUseTabs( True )
		self.SetTabIndents( 4 )
		self.SetIndent( 4 )
		self.SetIndentationGuides( True )
		self.SetCaretPeriod( 100 )
		self.SetCaretWidth( 4 )
		self.SetCaretForeground( "#FF0000" )

		self.StyleSetSpec( stc.STC_STYLE_LINENUMBER, "back:%s" % common.sui_colors("gray80") )
		self.StyleSetSpec( stc.STC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF, bold" )
		self.StyleSetSpec( stc.STC_STYLE_BRACEBAD  , "fore:#FFFFFF,back:#FF0000, bold" )

		# normal html
		self.StyleSetSpec( stc.STC_H_DEFAULT, "fore:%s" % common.sui_colors("darkslategray") )
		self.StyleSetSpec( stc.STC_H_TAG, "fore:#4433CC,bold" )
		self.StyleSetSpec( stc.STC_H_TAGUNKNOWN, "fore:#CC0055,back:%s,bold" % common.sui_colors("cornsilk") )
		self.StyleSetSpec( stc.STC_H_ATTRIBUTE, "fore:#336655" ) # #336655
		self.StyleSetSpec( stc.STC_H_ATTRIBUTEUNKNOWN, "fore:%s,back:%s" % ( common.sui_colors("indianred"), common.sui_colors("cornsilk") ) ) #fore:#555588
		self.StyleSetSpec( stc.STC_H_DOUBLESTRING, "fore:#888822" )
		self.StyleSetSpec( stc.STC_H_NUMBER, "fore:#992299" )
		self.StyleSetSpec( stc.STC_H_COMMENT, "fore:#11AA33,back:#EEFFEE" )
		# javascript
		self.StyleSetSpec( stc.STC_HJ_DEFAULT, "back:#ffefef,fore:%s,eol" % common.sui_colors("mediumslateblue") )
		self.StyleSetSpec( stc.STC_HJ_SYMBOLS, "back:#ffefef,fore:%s,bold" % common.sui_colors("indianred") )
		self.StyleSetSpec( stc.STC_HJ_WORD, "back:#ffefef,fore:#4433CC,bold" )
		self.StyleSetSpec( stc.STC_HJ_REGEX, "fore:#CC0055,back:%s,bold" % common.sui_colors("cornsilk") )
		self.StyleSetSpec( stc.STC_HJ_SINGLESTRING, "back:#ffefef,fore:#336655" ) # #336655
		self.StyleSetSpec( stc.STC_HJ_KEYWORD, "fore:%s,back:%s,bold" % ( common.sui_colors("indianred"), common.sui_colors("cornsilk") ) ) #fore:#555588
		self.StyleSetSpec( stc.STC_HJ_DOUBLESTRING, "back:#ffefef,fore:#888822" )
		self.StyleSetSpec( stc.STC_HJ_NUMBER, "back:#ffefef,fore:#992299" )
		self.StyleSetSpec( stc.STC_HJ_COMMENT, "fore:#11aa44,back:#ffefef,eol" )
		self.StyleSetSpec( stc.STC_HJ_COMMENTLINE, "fore:#11aa44,back:#ffefef,eol" )
		self.StyleSetSpec( stc.STC_HJ_COMMENTDOC, "fore:#11aa44,back:#ffefef,eol" )
		# Use our own context menu
